#include "signal_catch.h"

#include "data_cache.h"
#include "public_define.h"
#include <typeinfo>
#include "busesp.pb.h"
// #include "dnp_debug.pb.h"
#include "mcu_stm.pb.h"
#include "pnc.pb.h"
#include "hmi_basic_parkinternal.pb.h"

using namespace DcAdr;
using namespace std;


//topic与topicid的唯一映射，
map<string, int> g_map_topic_id = {
    {"sab-BusespProto.BusEsp", TOPIC_ID_sab_BusespProto_BusEsp},
    {"sab-VcuProto.Vcu", TOPIC_ID_sab_VcuProto_Vcu,},
    {"control-LONProto.LongCtrlCmdOutProto", TOPIC_ID_control_LONProto_LongCtrlCmdOutProto},
    {"state_switch-Sts.FromSTS", TOPIC_ID_state_switch_Sts_FromSTS},
    {"sas_com-SasProto.AebResult", TOPIC_ID_sas_com_SasProto_AebResult},
    {"sas_com-SasProto.LasResult", TOPIC_ID_sas_com_SasProto_LasSystemState},
    {"hmi_interface-HmiInterface.BasicStateFusion", TOPIC_ID_hmi_interface_HmiInterface_BasicStateFusion},
    {"sab-BusepsProto.BusEps", TOPIC_ID_sab_BusepsProto_BusEps},
    {"pnc-pnc.PlanningOutput", TOPIC_ID_pnp_pnp_PlanningOutput},
    {"hmi_interface-HmiInterface.HmiParkInternal", TOPIC_ID_hmi_interface_HmiInterface_HmiParkInternal},
};
// map for signal catches
map<string, T_Signal_data_info> g_data_catch;



int inner_event_get_topic_id(string topic_name)
{
    if(0 == g_map_topic_id.count(topic_name))
    {
        return -1;
    }
    return g_map_topic_id[topic_name];
}


/****************************************** sig_map  start  *****/

void save_signal_to_map(string signalname, T_Signal_data_info data_info)
{
    g_data_catch[signalname] = data_info;
    Log_Info(" [save_signal_to_map] key:{}",signalname);
    Log_Info(" [save_signal_to_map] datatype:{}",to_string(data_info.type));
}


void save_signal_to_map(string signalname, uint32_t data)
{
    T_Signal_data_info data_info;
    data_info.type = e_uint32;
    data_info.union_dataValue.data_uint32 = data;

    g_data_catch[signalname] = data_info;

}

void save_signal_to_map(string signalname, int32_t data)
{
    T_Signal_data_info data_info;
    data_info.type = e_int32;
    data_info.union_dataValue.data_int32 = data;

    g_data_catch[signalname] = data_info;
}

void save_signal_to_map(string signalname, uint64_t data)
{
    T_Signal_data_info data_info;
    data_info.type = e_uint64;
    data_info.union_dataValue.data_uint64 = data;

    g_data_catch[signalname] = data_info;
}

void save_signal_to_map(string signalname, int64_t data)
{
    T_Signal_data_info data_info;
    data_info.type = e_int64;
    data_info.union_dataValue.data_int64 = data;

    g_data_catch[signalname] = data_info;
}

void save_signal_to_map(string signalname, double data)
{
    T_Signal_data_info data_info;
    data_info.type = e_double;
    data_info.union_dataValue.data_double = data;

    g_data_catch[signalname] = data_info;
}

void save_signal_to_map(string signalname, float data)
{
    T_Signal_data_info data_info;
    data_info.type = e_float;
    data_info.union_dataValue.data_float = data;

    g_data_catch[signalname] = data_info;
}

void save_signal_to_map(string signalname, bool data)
{
    T_Signal_data_info data_info;
    data_info.type = e_bool;
    data_info.union_dataValue.data_bool = data;

    g_data_catch[signalname] = data_info;
}


void get_signal_from_map(string signalname, uint32_t *data)
{
    //T_Signal_data_info data_info = {0};
    T_Signal_data_info data_info = {};
    data_info.type = 0xFF;
    if(g_data_catch.count(signalname) != 0)
    {
        data_info = g_data_catch[signalname];
    }
    else
    {
        // Log_Signal(" trigger signal not find key:{}",signalname);
    }

    if(e_uint32 == data_info.type)
    {
        *data = data_info.union_dataValue.data_uint32;
    }
}

void get_signal_from_map(string signalname, int32_t *data)
{
    //T_Signal_data_info data_info = {0};
    T_Signal_data_info data_info = {};
    data_info.type = 0xFF;
    if(g_data_catch.count(signalname) != 0)
    {
        data_info = g_data_catch[signalname];
    }
    else
    {
        // Log_Signal(" trigger signal not find key:{}",signalname);
    }

    if(e_int32 == data_info.type)
    {
        *data = data_info.union_dataValue.data_int32;
    }
}

void get_signal_from_map(string signalname, uint64_t *data)
{
    //T_Signal_data_info data_info = {0};
    T_Signal_data_info data_info = {};
    data_info.type = 0xFF;
    if(g_data_catch.count(signalname) != 0)
    {
        data_info = g_data_catch[signalname];
    }
    else
    {
        // Log_Signal(" trigger signal not find key:{}",signalname);
    }

    if(e_uint64 == data_info.type)
    {
        *data = data_info.union_dataValue.data_uint64;
    }
}

void get_signal_from_map(string signalname, int64_t *data)
{
    //T_Signal_data_info data_info = {0};
    T_Signal_data_info data_info = {};
    data_info.type = 0xFF;
    if(g_data_catch.count(signalname) != 0)
    {
        data_info = g_data_catch[signalname];
    }
    else
    {
        // Log_Signal(" trigger signal not find key:{}",signalname);
    }

    if(e_int64 == data_info.type)
    {
        *data = data_info.union_dataValue.data_int64;
    }
}

void get_signal_from_map(string signalname, double *data)
{
    //T_Signal_data_info data_info = {0};
    T_Signal_data_info data_info = {};
    data_info.type = 0xFF;
    if(g_data_catch.count(signalname) != 0)
    {
        data_info = g_data_catch[signalname];
    }
    else
    {
        // Log_Signal(" trigger signal not find key:{}",signalname);
    }

    if(e_double == data_info.type)
    {
        *data = data_info.union_dataValue.data_double;
    }
}

void get_signal_from_map(string signalname, float *data)
{
    //T_Signal_data_info data_info = {0};
    T_Signal_data_info data_info = {};
    data_info.type = 0xFF;
    if(g_data_catch.count(signalname) != 0)
    {
        data_info = g_data_catch[signalname];
    }
    else
    {
        // Log_Signal(" trigger signal not find key:{}",signalname);
    }

    if(e_float == data_info.type)
    {
        *data = data_info.union_dataValue.data_float;
    }
}

void get_signal_from_map(string signalname, bool *data)
{
    //T_Signal_data_info data_info = {0};
    T_Signal_data_info data_info = {};
    data_info.type = 0xFF;
    if(g_data_catch.count(signalname) != 0)
    {
        data_info = g_data_catch[signalname];
    }
    else
    {
        // Log_Signal(" trigger signal not find key:{}",signalname);
    }

    if(e_bool == data_info.type)
    {
        *data = data_info.union_dataValue.data_bool;
    }
}
/****************************************** sig_map  end  *****/



//信号的key采用 sigkey_  + message + 最后那个信号名
void data_parese_BusEsp (const ProtoData &data) {

    BusespProto::BusEsp message;
    message.ParsePartialFromString(*data.data.get());
    save_signal_to_map("sigkey_BusEsp_esp_long_accel", message.esp_motion_info().esp_long_accel());
    save_signal_to_map("sigkey_BusEsp_esp_long_accel_valid", message.esp_motion_info().esp_long_accel_valid()); 
    save_signal_to_map("sigkey_BusEsp_esp_lat_accel_valid", message.esp_motion_info().esp_lat_accel_valid()); 
    save_signal_to_map("sigkey_BusEsp_esp_lat_accel", message.esp_motion_info().esp_lat_accel()); 
    save_signal_to_map("sigkey_BusEsp_esp_veh_spd", message.esp_motion_info().esp_veh_spd());         
    save_signal_to_map("sigkey_BusEsp_esp_tcs_failr", message.esp_func_sts().esp_tcs_failr());        
}
void data_parese_Vcu (const ProtoData &data) {

    VcuProto::Vcu message;
    message.ParsePartialFromString(*data.data.get());
    save_signal_to_map("sigkey_Vcu_ib_brk_pedl_sts_gb", message.vcu_pedl().ib_brk_pedl_sts_gb());
    save_signal_to_map("sigkey_Vcu_vcu_ovrd_mod_req", message.vcu_engine().vcu_ovrd_mod_req());   
    save_signal_to_map("sigkey_Vcu_vcu_pt_tq_req_avl", message.vcu_engine().vcu_pt_tq_req_avl());   
}
void data_parese_LongCtrlCmdOutProto (const ProtoData &data) {

    LONProto::LongCtrlCmdOutProto message;
    message.ParsePartialFromString(*data.data.get());
    save_signal_to_map("sigkey_LongCtrlCmdOutProto_acc_acctrqreq", message.acc_acctrqreq());
    save_signal_to_map("sigkey_LongCtrlCmdOutProto_acc_acctrqreqena", message.acc_acctrqreqena());
    save_signal_to_map("sigkey_LongCtrlCmdOutProto_acc_targetacceleration", message.acc_targetacceleration());
    save_signal_to_map("sigkey_LongCtrlCmdOutProto_acc_cddaxena", message.acc_cddaxena());
}
void data_parese_FromSTS (const ProtoData &data) {

    Sts::FromSTS message;
    message.ParsePartialFromString(*data.data.get());
    save_signal_to_map("sigkey_FromSTS_sys_latstate", message.sys_state_mng().sys_latstate());
    save_signal_to_map("sigkey_FromSTS_pd_status", message.pd_sts_mng().pd_status());
    save_signal_to_map("sigkey_FromSTS_sys_lngstate", message.sys_state_mng().sys_lngstate());
    save_signal_to_map("sigkey_FromSTS_takeover_alarm_lat_level", message.safety_strategy_mng().takeover_alarm_lat_level());
    save_signal_to_map("sigkey_FromSTS_takeover_alarm_lng_level", message.safety_strategy_mng().takeover_alarm_lng_level());
    save_signal_to_map("sigkey_FromSTS_apa_status", message.park_statemachine().apa_status());
    save_signal_to_map("sigkey_FromSTS_park_sst_req", message.park_sst_mng().park_sst_req());
    save_signal_to_map("sigkey_FromSTS_park_sst_notice", message.park_sst_mng().park_sst_notice());
}
void data_parese_AebResult (const ProtoData &data) {

    SasProto::AebResult message;
    message.ParsePartialFromString(*data.data.get());
    save_signal_to_map("sigkey_AebResult_fcw_active", message.fcw_active());
    save_signal_to_map("sigkey_AebResult_awb_active", message.awb_active());
}
void data_parese_LasSystemState (const ProtoData &data) {

    SasProto::LasResult message;
    message.ParsePartialFromString(*data.data.get());
    save_signal_to_map("sigkey_LasSystemState_elk_state", message.elk_state());
}
void data_parese_BasicStateFusion (const ProtoData &data) {

    HmiInterface::BasicStateFusion message;
    message.ParsePartialFromString(*data.data.get());
    save_signal_to_map("sigkey_BasicStateFusion_ad_lattakeoverreq", message.status_fusion().takeovereyewarning().ad_lattakeoverreq());
    save_signal_to_map("sigkey_BasicStateFusion_ad_lngtakeoverreq", message.status_fusion().takeovereyewarning().ad_lngtakeoverreq());

}
void data_parese_HmiParkInternal (const ProtoData &data) {

    HmiInterface::HmiParkInternal message;
    message.ParsePartialFromString(*data.data.get());
    save_signal_to_map("sigkey_HmiParkInternal_hmi_apadrvrreqonoff", message.hmi_apadrvrreqonoff());
}
void data_parese_BusEps (const ProtoData &data) {

    BusepsProto::BusEps message;
    message.ParsePartialFromString(*data.data.get());
    save_signal_to_map("sigkey_BusEps_eps_steer_ag_rate", message.sas().eps_steer_ag_rate());
    save_signal_to_map("sigkey_BusEps_eps_measured_torsion_bar_torque", message.eps_motion_info().eps_measured_torsion_bar_torque());
    save_signal_to_map("sigkey_BusEps_eps_measured_torsion_bar_torq_valid", message.eps_motion_info().eps_measured_torsion_bar_torq_valid());
    save_signal_to_map("sigkey_BusEps_eps_faild", message.eps_sts().eps_faild());
    
}

//<LDP_纵向规划原始减速度>软件接口还没有开发 临时方案
void data_parese_PlanningOutput (const ProtoData &data) {

    pnc::PlanningOutput message;
    message.ParsePartialFromString(*data.data.get());
    save_signal_to_map("sigkey_PlanningOutput_accel_ref", message.planned_speed_ego().accel_ref());
}



void topic_data_parse_and_save(const ProtoData &data)
{
    int data_parse_and_save_id = 0;

    std::string topic = *data.topic.get(); 

    data_parse_and_save_id = inner_event_get_topic_id(topic);
    if(data_parse_and_save_id < 0)
    {
        return;
    }

    switch (data_parse_and_save_id){
        case TOPIC_ID_sab_BusespProto_BusEsp:
        {
            data_parese_BusEsp(data);
            break;
        }
        case TOPIC_ID_sab_VcuProto_Vcu:
        {
            data_parese_Vcu(data);
            break;
        }
        case TOPIC_ID_control_LONProto_LongCtrlCmdOutProto:
        {
            data_parese_LongCtrlCmdOutProto(data);
            break;
        }
        case TOPIC_ID_state_switch_Sts_FromSTS:
        {
            data_parese_FromSTS(data);
            break;
        }
        case TOPIC_ID_sas_com_SasProto_AebResult:
        {
            data_parese_AebResult(data);
            break;
        }
        case TOPIC_ID_sas_com_SasProto_LasSystemState:
        {
            data_parese_LasSystemState(data);
            break;
        }
        case TOPIC_ID_sab_BusepsProto_BusEps:
        {
            data_parese_BusEps(data);
            break;
        }
        case TOPIC_ID_hmi_interface_HmiInterface_BasicStateFusion:
        {
            data_parese_BasicStateFusion(data);
            break;
        }  
        case TOPIC_ID_pnp_pnp_PlanningOutput:
        {
            data_parese_PlanningOutput(data);
            break;
        }
        case TOPIC_ID_hmi_interface_HmiInterface_HmiParkInternal:
        {
            data_parese_HmiParkInternal(data);
            break;
        }        
        default :
            break;
    }

    return;
}
